package com.erp.hr.base.service.impl;

import com.erp.dataset.dao.SysDatasetDao;
import com.erp.hr.base.dao.BaseDao;
import com.erp.hr.base.model.BaseModel;
import com.erp.hr.base.service.BaseService;
import com.erp.hr.base.util.CommonUtils;
import com.erp.hr.dao.model.HrStaff;
import com.erp.hr.dao.model.HrStaffDepartmentVO;
import com.erp.hr.dao.model.HrStaffInfoRO;
import com.erp.hr.service.HrCommonService;
import com.erp.hr.service.HrDepartmentService;
import com.erp.hr.service.HrStaffDepartmentRService;
import org.redragon.framework.hibernate.model.Pages;
import org.redragon.framework.util.ShiroUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

/**
 * 业务实现层基类
 * @Author: syz
 * @blame syz
 * @CreateTime: 2021/4/6
 */
@Transactional(rollbackFor=RuntimeException.class)
public abstract class BaseServiceImpl<M extends BaseDao<T>, T extends BaseModel> implements BaseService<T> {

    @Autowired
    protected M dao;

    /**
     * 数据字典dao
     */
    @Autowired
    private SysDatasetDao sysDatasetDao;

    /**
     * 职员服务
     */
    @Autowired
    private HrCommonService hrCommonService;

    /**
     * 部门服务
     */
    @Autowired
    private HrDepartmentService hrDepartmentService;

    /**
     * 员工部门服务
     */
    @Autowired
    private HrStaffDepartmentRService hrStaffDepartmentRService;


    /**
     * 根据键获取数据字典集合
     * @param key 键
     * @return 数据字典集合
     */
    @Override
    public Map<String, String> getDictByKey(String key) {
        return sysDatasetDao.getDatasetMap(key);
    }

    /**
     * 获取当前登录职员信息
     * @return 职员信息
     */
    @Override
    public HrStaffInfoRO getStaffInfo() {
        return hrCommonService.getStaffInfo(ShiroUtil.getPrincipal());
    }

    /**
     * 根据部门编号获取部门下所有员工编号
     * @param departmentCode 部门编号
     * @return 部门下所有员工编号
     */
    protected List<String> getStaffCodeByDepartment(String departmentCode) {
        List<HrStaffDepartmentVO> list = hrCommonService.getStaffByDepartment(departmentCode);
        List<String> result = new ArrayList<>(list.size());
        for (HrStaffDepartmentVO hsd : list) {
            result.add(hsd.getStaff_code());
        }
        return result;
    }

    /**
     * 是否为总部
     * @param companyCode 公司编码
     * @return 是否为总部
     */
    protected boolean isHeadOffice(String companyCode) {
        return "0".equals(hrDepartmentService.getDataObject(companyCode).getIscompany());
    }

    /**
     * 获取审批人员编码字符串
     * @param codes 审批部门集合
     * @param positionId 审批岗位id
     * @return 审批人员编码字符串
     */
    protected Set<String> getCodeSetByDepartmentCode(Set<String> codes, String positionId) {
        Set<String> result = new HashSet<>();
        for (String code : codes) {
            List<HrStaffDepartmentVO> staffByPosition = hrCommonService.getStaffByPosition(code, positionId);
            if (staffByPosition != null && !staffByPosition.isEmpty()) {
                for (HrStaffDepartmentVO hrStaffDepartmentVO : staffByPosition) {
                    result.add(hrStaffDepartmentVO.getStaff_code());
                }
            }
        }
        return result;
    }

    /**
     * 获取审批人员编码字符串
     * @param positionId 审批岗位id
     * @return 审批人员编码字符串
     */
    protected Set<String> getCodeSetByCompanyCode(String positionId) {
        Set<String> result = new HashSet<>();
        List<HrStaff> list = hrStaffDepartmentRService.getAllStaffByPostCode(positionId);
        if (list != null && !list.isEmpty()) {
            for (HrStaff hrStaff : list) {
                result.add(hrStaff.getStaffCode());
            }
        }
        return result;
    }

    /**
     * 获取审批人员编码字符串
     * @param codes 审批部门集合
     * @param positionId 审批岗位id
     * @return 审批人员编码字符串
     */
    protected Set<String> getCodeSetByCompanyCode(Set<String> codes, String positionId) {
        Set<String> result = new HashSet<>();
        for (String code : codes) {
            List<HrStaff> list = hrStaffDepartmentRService.getAllStaffByPostCode(code, positionId);
            if (list != null && !list.isEmpty()) {
                for (HrStaff h : list) {
                    result.add(h.getStaffCode());
                }
            }
        }
        return result;
    }

    /**
     * 获取集合元素的id并以集合形式返回
     * @param list 需要获取id集合的集合
     * @param <E> BaseModel
     * @return id集合
     */
    @Override
    public <E extends BaseModel> Set<Long> getIdList(List<E> list) {
        Set<Long> idList = new HashSet<>();
        for (E e : list) {
            idList.add(e.getId());
        }
        return idList;
    }

    /**
     * 获取集合元素的id并返回非空集合
     * @param list 需要获取id集合的集合
     * @param <E> StrIdBaseEntity的子类
     * @return 非空id集合
     */
    @Override
    public <E extends BaseModel> Set<Long> getNotEmptyIdList(List<E> list) {
        Set <Long> idList = getIdList(list);
        if (idList.size() == 0){
            idList.add(0L);
        }
        return idList;
    }

    /**
     * 设置对象新建信息
     * @param e 需要设置新建信息的对象
     * @param <E> BaseModel的子类
     */
    protected <E extends BaseModel> void setCreateInfo(E e) {
        String staffCode = getStaffInfo().getStaffCode();
        Date now = new Date();
        e.setIsDel(CommonUtils.IS_DEL_NO);
        e.setCreateUser(staffCode);
        e.setCreateTime(now);
        e.setUpdateUser(staffCode);
        e.setUpdateTime(now);
    }

    /**
     * 设置对象更新信息
     * @param e 需要设置更新信息的对象
     * @param <E> BaseModel的子类
     */
    protected <E extends BaseModel> void setUpdateInfo(E e) {
        e.setUpdateUser(getStaffInfo().getStaffCode());
        e.setUpdateTime(new Date());
    }

    @Override
    public void insertDataObject(T t) {
        dao.insertDataObject(t);
    }

    @Override
    public void updateDataObject(T t) {
        dao.updateDataObject(t);
    }

    @Override
    public void insertOrUpdateDataObject(T t) {
        dao.insertOrUpdateDataObject(t);
    }

    @Override
    public void deleteDataObject(T t) {
        dao.deleteDataObject(t);
    }

    @Override
    public List<T> getDataObjects() {
        return dao.getDataObjects();
    }

    @Override
    public T getDataObject(int i) {
        return dao.getDataObject(i);
    }

    @Override
    public T getDataObject(String s) {
        return dao.getDataObject(s);
    }

    @Override
    public List<T> getDataObjects(T t) {
        return dao.getDataObjects(t);
    }

    @Override
    public List<T> getDataObjects(Pages pages) {
        return dao.getDataObjects(pages);
    }

    @Override
    public List<T> getDataObjects(Pages pages, T t) {
        return dao.getDataObjects(pages, t);
    }

    @Override
    public List<Map<String, Object>> getDataObjectsArray(Pages pages, T t) {
        return dao.getDataObjectsArray(pages, t);
    }

    @Override
    public List<T> getDataObjectsForDataAuth(String s, Pages pages, T t) {
        t.setCreateUser(getStaffInfo().getStaffCode());
        return dao.getDataObjectsForDataAuth(s, pages, t);
    }

}